#pragma once

/********************************************************************
	Module    :
	Filename  : 	e:\Application\GuiDll\GuiSrc\Control\Control.h
	Author    :		Leon
	Version   :		1.01
	Date	  :		9:10:2008   14:18
	Function  :
    Remark    :

    Modify history:
=====================================================================
    Date      :
    Modifier  :
    Item      :
=====================================================================



*********************************************************************/

#include "../Gui.h"
#include "Misc.h"
#include "Gdi.h"

class CContainer;

//ctrl left btn click state
#define CLICK_DOWN			0x00000001
#define CLICK_UP			0x00000002
#define CLICK_DOUBLE		0x00000004
#define CLICK_LONG		     0x00000008
//ctrl type
#define SWS_STATICTEXT		0x00000018
#define SWS_STATIC			0x00000008
#define SBS_ACTIVE			0x8000000
#define SBS_ROUND			0x0001000
#define SBS_RECT			0x0000001


#define STATE_NORMAL		0x00000001
#define STATE_PUSHED		0x00000002
#define STATE_FOCUS			0x00000004
#define STATE_DISABLED		0x00000008
#define STATE_NOUPIME		0x00000009

#define BEGIN_FONT_SELECTION 	HFONT hOldFont = NULL;\
					if(m_pFont)\
					{\
						hOldFont = pDC->SelectFont(m_pFont->m_hFont);\
					}\

#define END_FONT_SELECTION  if(hOldFont)\
					{\
						pDC->SelectFont(hOldFont);\
					}\

/**
 *@brief The base control class. \n All the other controls  should
 * inherited form it
 *
 */

extern int g_ID; 

class GUI_API CControl
{
public:
	CControl(){};
	/**
	*@param[in]  nID		 Specifies the  ID       of the control
	*/
	CControl(UINT nID);
	/**
	*@param[in]  strCaption  Specifies the  caption  of the control 
	*@param[in]  nID		 Specifies the  ID       of the control
	*/
	CControl(wstring strCaption,UINT nID);
	/**
	*@param[in]  dwStyle Specifies the  style of the control
	*@li @c SWS_STATIC   static control without any vents
	*@li @c SBS_ACTIVE  
	*@li @c SBS_ROUND
	*@li @c SBS_RECT
	*@param[in]  strCaption  Specifies the  caption  of the control 
	*@param[in]  rc           Specifies the  position of the control
	*@param[in]  nID		 Specifies the  ID       of the control
	*/
	CControl(DWORD dwStyle, wstring strCaption,const CRect rc, UINT nID);
	/**
	*@param[in]  dwStyle Specifies the  style of the control
	*@li @c SWS_STATIC   static control without any vents
	*@li @c SBS_ACTIVE  
	*@li @c SBS_ROUND
	*@li @c SBS_RECT
	*@param[in]  strCaption  Specifies the  caption  of the control 
	*@param[in]  x           Specifies the  position of the left side of the control
	*@param[in]  y           Specifies the  position of the top  side of the control
	*@param[in]  cx          Specifies the  position of the width of the control
	*@param[in]  cy          Specifies the  position of the control
	*@param[in]  nID		 Specifies the  ID       of the control
	*/
	CControl(DWORD dwStyle, wstring strCaption, int x, int y, int cx, int cy, UINT nID);
	virtual ~CControl(void);

public:

	/**
	 *@brief This function draws the control itself. All the the inherited class have to overload this function \n
	 *It will called by the ContainerPainer
	 *@param[in] pDC  To issue the flicker problem,you have to pass a temporary DC
	 *@see CDC, CClientDC,CWindowDC,CContainerPainter::Paint(CDC* pDc, CContainer* pContainer, CRect& rc)
	 *@return  No return value
	 */

	virtual void Paint(CDC* pDC);

	/**
	*@brief This function responses to the left button down and left button up event \n
	*@param[in] dwClick  Indicates whether various virtual keys are down. This parameter can be any combination of the following values:
	*@li @c CLICK_DOWN    click  down
	*@li @c CLICK_UP      click  up
	*@li @c CLICK_DOUBLE  double click
	*
	*@param[in] pt  Specifies the x- and y-coordinate of the cursor. These coordinates are always relative to the upper-left corner of the window.
	*@return  No return value
	*/

	virtual void Click(DWORD dwClick, POINT pt);

	/**
	*@brief This function responses to draw the background of the control
	*@param[in] pDC  To issue the flicker problem,you have to pass a temporary DC
	*@return  No return value
	*/

	virtual void PaintBackGnd(CDC* pDC);

	/**
	*@brief Set The container
	*@param[in] pContainer  the destination container pointer
	*@see CContainer
	*@return  No return value
	*/

	inline void SetContainer(CContainer* pContainer)
	{
		m_pContainer = pContainer;
	}

    CContainer* GetContainer(){
		return m_pContainer;
	}

	/**
	*@brief Set the control ID,the value will post to the window like this PostMessage(m_pContainer->m_hWnd,WM_COMMAND, m_nID,NULL);
	*@param[in] nID  the unique ID for the control
	*@return  No return value
	*/

	inline void SetID(UINT nID)
	{
		m_nID = nID;
	}

	/**
	*@brief Get the control ID
	*@return  The control ID
	*/

	inline int GetID()
	{
		return m_nID;
	}

	/**
	*@brief Set the caption of the control
	*@param[in] nID  The caption
	*@return  No return value
	*/

	void SetCaption(wstring strCaption)
	{
		m_strCaption = strCaption;
	}

	/**
	*@brief Get the caption of the control
	*@return  The caption
	*/
	inline wstring GetCaption()
	{
		return m_strCaption;
	}

	/**
	*@brief Show or hide the control
	*@param[in] bShow  Indicates whether to show or hide the control
	*@li @c TRUE   Show the control
	*@li @c FALSE  Hide the control
	*
	*@return  No return value
	*/

	void Show(BOOL bShow = TRUE);

	/**
	*@brief Check if the control is visible
	*@retval TRUE The control is visible
	*@retval FALSE THe control is invisible
	*/

	inline BOOL IsVisible()
	{
		return m_bVisibale;
	}

	/**
	*@brief This function returns the control style
	*@li @c SWS_STATIC  static control without any vents
	*@li @c SBS_ACTIVE  
	*@li @c SBS_ROUND
	*@li @c SBS_RECT
	*@return  The control style
	*/

	inline DWORD GetStyle()
	{
		return m_dwStyle;
	}

	inline void SetStyle(DWORD dwStyle)
	{
		m_dwStyle = dwStyle;
	}

	/**
	*@brief Get the control rect in the container
	*@return  The control position
	*/

	inline CRect& GetRect()
	{
		return m_rcControl;
	}

	inline CRect& GetRectCopy()
	{
		return m_rcControlCopy;
	}
	/**
	*@brief Set the control rect in the container
	*@param[in]  x   Specifies the new position of the left side of the control
	*@param[in]  y   Specifies the new position of the top  side of the control
	*@param[in]  cx  Specifies the new position of the width of the control
	*@param[in]  cy  Specifies the new position of the height  of the control
	*@return  No return value
	*/
	inline void SetRect(int x,int y,int cx,int cy)
	{
		m_rcControl.SetRect(x,y,x+cx,y+cy);
	}

	/**
	*@brief Set the control rect in the container    
	*@param[in] rc   Specifies the new position of the control
	*@return  No return value
	*/
	inline void SetRect(CRect& rc)
	{
		m_rcControl = rc;
	}

	/**
	*@brief Set the control data   
	*@param[in] dwData  Specifies the new data of the control
	*@return  No return value
	*/

	inline void SetData(DWORD_PTR dwData)
	{
		m_dwData = dwData;
	}

	/**
	*@brief Get the control data
	*@return  The control data
	*/

	inline DWORD_PTR GetData()
	{
		return m_dwData;
	}

	/**
	*@brief Set the control font
	*@param[in]  pFont The pointer of the data
	*@return  No return value
	*/
	inline void SetFont(CFont *pFont) 
	{
		m_pFont = pFont;
	}

	/**
	*@brief Get the control font pointer
	*@return  the control font pointer
	*/

	inline CFont* GetFont()
	{
		return m_pFont;
	}

	/**
	*@brief Set control new state
	*@param[in] dwStyle The control new style
	*@li @c STATE_NORMAL      Set the control in normal state
	*@li @c STATE_PUSHED      Set the control in pushed state
	*@li @c STATE_FOCUS       Set the control in active state
	*@li @c STATE_DISABLED    Disable the control
	*@li @c STATE_NOUPIME     
	*/

	inline void SetState(DWORD dwStyle)
	{
		m_nState = dwStyle;
	}

	/**
	*@brief Get the control  state
	*@return  The control  state
	*@li @c STATE_NORMAL      Set the control in normal state
	*@li @c STATE_PUSHED      Set the control in pushed state
	*@li @c STATE_FOCUS       Set the control in active state
	*@li @c STATE_DISABLED    Disable the control
	*@li @c STATE_NOUPIME     
	*/

	inline DWORD GetState()
	{
		return m_nState;
	}

	/**
	*@brief Set the new normal state text color
    *@param clr The normal state text color
	*@return  No return value
	*/
	inline void SetTxtNormal(COLORREF clr)
	{
		m_clrTxtNormal = clr;
	}

	/**
	*@brief Get the new text align style
	*@return  The normal text color
	*/

	inline COLORREF GetTxtNormal()
	{
		return m_clrTxtNormal;
	}

	/**
	*@brief Set the new active state text color
	*@param clr The active state text color
	*@return  No return value
	*/
	inline void SetTxtActive(COLORREF clr)
	{
		m_clrTxtActive = clr;
	}

	/**
	*@brief Get the new text align style
	*@return  The active text color
	*/

	inline COLORREF GetTxtActive()
	{
		return m_clrTxtActive;
	}

	/**
	*@brief Set the new text align style
	*@param dwAlign The active align style
	*@return  No return value
	*/
	inline void SetAlign(DWORD dwAlign)
	{
		m_dwAlign = dwAlign;
	}

	inline BOOL IsEnabled()
	{
		return m_bEnabled;
	}

	void Enable(BOOL bEnable);
	

protected:
	wstring		m_strCaption;
	DWORD		m_dwStyle;
	CFont*		m_pFont;
	UINT		m_nID;                       
	CRect		m_rcControl;             
	CRect		m_rcControlCopy;   
	DWORD_PTR	m_dwData;                  
	CContainer*	m_pContainer;	
	DWORD		m_nState;
	DWORD		m_dwAlign;
	COLORREF	m_clrTxtActive;
	COLORREF	m_clrTxtNormal;
	BOOL		m_bEnabled;
	BOOL		m_bVisibale;
	friend class CContainer;
};
